using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Boa.HD.AccesoDatos.Entidades;
using Boa.HD.AccesoDatos.Contratos;
using Boa.HD.Negocios.Servicios;
using Boa.HD.Negocios.Excepciones;
using Boa.HD.Negocios.Session;
using Boa.HD.AccesoDatos.Entidades.DTO;

namespace Boa.HD.Negocios
{
   /// <summary>
   /// Implementacion de la interface IHD_AsignacionTecnicoProblemaNegociosServicio, los metodos que estan definidos en el contrato IHD_AsignacionTecnicoProblemaNegociosServicio serán accesibles desde un contexto externo
   /// </summary>	
   public class HD_AsignacionTecnicoProblemaNegocios : IHD_AsignacionTecnicoProblemaNegociosServicio
   {
	private IHD_AsignacionTecnicoProblemaAccesoDatos accesoDatos;
	public HD_AsignacionTecnicoProblemaNegocios()
	{		
		accesoDatos = DataFactory.Current.GetHD_AsignacionTecnicoProblemaAccesoDatos();
	}
	
	/// <summary>
    /// Devuelve una lista de HD_AsignacionTecnicoProblema's de las ocurrencias encontradas a partir del filtro
    /// </summary>    
	public List<HD_AsignacionTecnicoProblema> BuscarPorFiltro(string filtro)
	{
		return accesoDatos.BuscarPorFiltro(filtro).ToList();
	}

	#region operaciones básicas
	
	/// <summary>
    /// Elimina la entidad HD_AsignacionTecnicoProblema, lanzará una excepcion si la entidad guarda dependencia a otras entidades
    /// </summary>	
	public void Eliminar(HD_AsignacionTecnicoProblema entidad)
	{
		try
		{
		    accesoDatos.Delete(accesoDatos.GetById(entidad.Id));
	    }
		catch(Exception ex)
		{
		   throw new HD_AsignacionTecnicoProblemaEliminarExcepcion("HD_AsignacionTecnicoProblema");
		}
	}
	
	/// <summary>
    /// Devuelve HD_AsignacionTecnicoProblema, buscada por su Id, si no existe, entonces devuelve null
    /// </summary>	
	public HD_AsignacionTecnicoProblema ObtenerPorId(object Id)
	{
		return accesoDatos.GetById(Id);
	}

	/// <summary>
    /// Devuelve List<HD_AsignacionTecnicoProblema>, de todas la entidades de ese tipo
    /// </summary>	
	public List<HD_AsignacionTecnicoProblema> ObtenerTodas()
	{
		return accesoDatos.GetAll().ToList();
	}

	
	/// <summary>
    /// Guarda HD_AsignacionTecnicoProblema, previa ejecucion satisfactoria de las reglas de negocio
    /// </summary>	
	public HD_AsignacionTecnicoProblema Guardar(HD_AsignacionTecnicoProblema entidad)
	{
		//Agregar aqui las reglas de negocio.......	
		if(entidad==null)
		 throw new HD_AsignacionTecnicoProblemaRequeridoExcepcion(); 
		
		#region Foreign Keys Values
        if(entidad.DefinicionProblemaId_FK > 0 && entidad.DefinicionProblema==null)
            entidad.DefinicionProblema = DataFactory.Current.GetHD_DefinicionProblemaAccesoDatos().GetById(entidad.DefinicionProblemaId_FK);
        if(entidad.TecnicoId_FK > 0 && entidad.Tecnico==null)
            entidad.Tecnico = DataFactory.Current.GetHD_TecnicoAccesoDatos().GetById(entidad.TecnicoId_FK);
        #endregion

        if (!entidad.HoraInicioDisponible.HasValue)
            entidad.HoraInicioDisponible = DateTime.Now;
        if (!entidad.HoraFinDisponible.HasValue)
            entidad.HoraFinDisponible = DateTime.Now;

        if (entidad.Id == 0)
        {
            if (ObtenerTodas().Where(p => p.DefinicionProblema.Id == entidad.DefinicionProblema.Id && p.Tecnico.Id == entidad.Tecnico.Id).Any())
            {
                throw new Exception("El tecnico " + entidad.Tecnico.Nombre + " ya tiene asignado el problema " + entidad.DefinicionProblema.Nombre);
            }        

            entidad.Guid = System.Guid.NewGuid().ToString();
            entidad.FechaAsignacion = DateTime.Now;
            entidad.HoraInicioDisponible = DateTime.Now;
            entidad.HoraFinDisponible = DateTime.Now.AddMonths(12);
            accesoDatos.Insert(entidad);
        }
        else
        {   
            accesoDatos.Update(entidad);
        }
		return entidad;
	}

	#endregion

    public List<HD_AsignacionTecnicoProblema> SolicitudesDeTecnicoSesion()
    {
        var usuario = Global.UserInfo();

        return accesoDatos.GetAll().Where(p => p.Tecnico.EmpleadoId == usuario.DtoBOAPersonal.EmpleadoId).ToList();

    }

       /// <summary>
       /// agregado 
       /// </summary>
       /// <param name="problema"></param>
       /// <returns></returns>
    public List<DtoTecnicoHoraAsignada> GuardarAsignacionParaTecnicoExterno(HD_DefinicionProblema problema)
    {
        HD_AsignacionTecnicoProblema asignTecnicoExterno = new HD_AsignacionTecnicoProblema();
        asignTecnicoExterno.Guid = System.Guid.NewGuid().ToString();
        asignTecnicoExterno.DefinicionProblema = problema;
        asignTecnicoExterno.FechaAsignacion = DateTime.Now;
        asignTecnicoExterno.Activo = true;
        asignTecnicoExterno.HoraFinDisponible = DateTime.Now;
        asignTecnicoExterno.HoraFinDisponible = DateTime.Now;

        var usuario = Global.UserInfo();
        var tecnicoExterno =  DataFactory.Current.GetHD_TecnicoAccesoDatos().GetAll().FirstOrDefault(p => p.EsExterno && p.EmpleadoId == 1);
        asignTecnicoExterno.Tecnico = tecnicoExterno;

           var existente =
               ObtenerTodas().FirstOrDefault(
                   p =>
                   p.DefinicionProblema.Id == asignTecnicoExterno.DefinicionProblema.Id &&
                   p.Tecnico.Id == asignTecnicoExterno.Tecnico.Id);
        if (existente==null)
        {
            Guardar(asignTecnicoExterno);
        }

        var data = new DtoTecnicoHoraAsignada()
                       {
                           AsignacionTecnicoProblemaId = existente!=null?existente.Id:asignTecnicoExterno.Id,
                           NombreTecnico = tecnicoExterno.Nombre,
                           DefinicionProblemaId = problema.Id,
                           NombreProblema = problema.Nombre,
                           MinutosOcupados = 0
                       };
        var ret = new List<DtoTecnicoHoraAsignada> {data};
        return ret;
    }

   }
}


